var tileContainer;

var horizontalStack = 'hor-stack';
var verticalStack = 'ver-stack';

/* ==================== Context menu item functions ================= */
function createTileContainer() {
    return $('<div></div>').addClass("tileContainer pseudo-new");
}

function getValue(ele, property) {
	return parseInt(ele.css(property));
}

function calculateLayout() {
	//reset all widths
    $('#content').find('div').removeAttr('style');
    
    //recalculate widths
    $('#content').find('.' + horizontalStack).each(function() {
        var outerWidth = $(this).outerWidth();
        var childCount = $(this).children().size();
        
        var widthAvailable = outerWidth - (childCount-1) * 10;
        var widthToAddPerChild =  Math.floor(widthAvailable/childCount);
        
        $(this).children().each(function() {
        	if($(this).is(':last-child')) {
                $(this).css('width', widthAvailable);
        	} else {
        		$(this).css('width', widthToAddPerChild);
        		widthAvailable -= widthToAddPerChild;
        	}
        });
    });
    
    //recalculate heights
    /*
     * this is necessary otherwise divs won't fill height of the parent
     */
    $('#content').find('.' + horizontalStack).each(function() {
    	//outer height is height of element excluding top/bottom margins
    	$(this).css('height', $(this).outerHeight());
    }); 
    
    /*
     * this is required because if you add divs to adjacent divs then divs in this container
     * will not fill all the height
     */
    $('#content').find('.' + verticalStack).each(function() {
    	var outerHeight = $(this).outerHeight();
        var childCount = $(this).children().size();
        
        var filledHeight = 0;
    	$(this).children().each(function(){
    		filledHeight += $(this).outerHeight(true);
    	});
        
    	var unfilledHeight = outerHeight - filledHeight;
        if(unfilledHeight > 0) {
	    	var heightToAddPerChild =  Math.floor(unfilledHeight/childCount);
	        
	        $(this).children().each(function() {
	        	var property = 'height';
	        	if($(this).hasClass('tileContainer')) {
	        		property = 'min-height';
	        	}
	        	if($(this).is(':last-child')) {
	        		var att
	                $(this).css(property, $(this).outerHeight() + unfilledHeight);
	        	} else {
	        		$(this).css(property, $(this).outerHeight() + heightToAddPerChild);
	        		unfilledHeight -= heightToAddPerChild;
	        	}
	        });
        }
    }); 
}

function addStack() {
	var tileContainerClone = tileContainer.clone().wrap('<div/>').parent().html();
	var newStack = $('<div class="container"></div>').append(tileContainerClone);
	tileContainer.replaceWith(newStack);
	
	//update tile container reference
	tileContainer = newStack.children(':first-child').addClass('pseudo-new');
	
	/*
	 * Before above operation this tile container may have zero or more siblings but after this
	 * operation it will have no siblings. So resetting this value.
	 */
	return 0;
}

function addContainer(loc) {
    var newTileContainer = createTileContainer();
    var siblings = tileContainer.siblings().size();
    
    switch (loc) {
        //right
        case 1:
        	/* 
        	 * if this tile container is inside a vertical stack we need to move this container to a new 
        	 * stack before adding a new container to its left or right.
        	 */
        	if(tileContainer.parent().hasClass(verticalStack)) {
        		siblings = addStack();
        	}
            newTileContainer.insertAfter(tileContainer);
            if(siblings == 0) {
                tileContainer.parent().addClass(horizontalStack);
            }
            break;
    
        //left
        case 2:
        	/* 
        	 * if this tile container is inside a vertical stack we need to move this container to a new 
        	 * stack before adding a new container to its left or right.
        	 */
        	if(tileContainer.parent().hasClass(verticalStack)) {
        		siblings = addStack();
        	}
            newTileContainer.insertBefore(tileContainer);
            if(siblings == 0) {
                tileContainer.parent().addClass(horizontalStack);
            }
            break;
        //above
        case 3:
        	/* 
        	 * if this tile container is inside a horizontal stack we need to move this container to a new 
        	 * stack before adding a new container on above or below this container.
        	 */
        	if(tileContainer.parent().hasClass(horizontalStack)) {
        		siblings = addStack();
        	}
            newTileContainer.insertBefore(tileContainer);
            if(siblings == 0) {
                tileContainer.parent().addClass(verticalStack);
            }
            break;
    
        //below
        case 4:
        	/* 
        	 * if this tile container is inside a horizontal stack we need to move this container to a new 
        	 * stack before adding a new container on above or below this container.
        	 */
        	if(tileContainer.parent().hasClass(horizontalStack)) {
        		siblings = addStack();
        	}
            newTileContainer.insertAfter(tileContainer);
            if(siblings == 0) {
                tileContainer.parent().addClass(verticalStack);
            }
            break;
        default:
            break;
    }
   
    tileContainerPostCreation();
    
    calculateLayout();
    
}

function deleteTileContainer() {
	
	var parent = tileContainer.parent();
	
	tileContainer.remove();
	
	if(parent.children().size() == 1) {
		parent.replaceWith(parent.children(':first'));
	}
	
	calculateLayout();
}

function hideContextMenu(){
    if(document.getElementById("contextMenu")) {
        document.body.removeChild(document.getElementById("contextMenu"));
    }
    return true;
}


function tileContainerPostCreation() {
	var tileContainerDropOptions = {
            accept: ".pseudo-controller",
            drop : function(event, ui) {
		            	var controllerId = ui.draggable.attr('piston-controller-id');
		                $('<p>' + ui.draggable.text() + '</p>')
		                	.append('<span class="pseudo-del">Del</span>')
		                	.addClass('tile pseudo-new')
		                	.attr('piston-controller-id', controllerId)
		                	.appendTo(this);
		                
		            	$(".tile.pseudo-new").disableSelection();
		                
		                if($(".tile.pseudo-new").siblings().size() == 1) {
        					$(".tile.pseudo-new").parent().sortable({
			            			placeholder: "tile sortable-placeholder",
			            			containment: "parent",
			            			cursor: "move",
			            			start: function(ev, ui) {
			            				$(this).css('height', $(this).outerHeight());
			            			},
			            			stop: function(ev, ui) {
			            				$(this).removeAttr("height", "");
			            			}
			            	});
		                }
		                
		                $(".tile.pseudo-new").removeClass('pseudo-new');
		                
		                /* 
		                 * add handler for click event on tile delete icon  
		                 */
		                $('.pseudo-del').bind("click", function(){
		                	//span --> .tile --> .tileContainer
		                	if($(this).parent().siblings().size() == 1) {
		                		$(this).parent().parent().sortable({ disabled: true });
		                	}
		                	$(this).parent().remove();
		                	calculateLayout();
		                });
		                
            			calculateLayout();
                   }
          };

	$(".tileContainer.pseudo-new").droppable(tileContainerDropOptions);
	
	/* ================================== Tile container context menu ===================================== */
	var ul = '#contextMenu';
	$('.tileContainer.pseudo-new').bind("contextmenu", function(ev) {
															tileContainer = $(this);
															
															//remove any existing context menu
															$(ul).remove();
															
															$('<ul></ul>').attr('id', 'contextMenu').addClass('tileContainer-contextMenu').hide().appendTo('body');
															
															if(tileContainer.parent().hasClass(horizontalStack)) {
																$('<li>Add Container (Right)</li>').attr("onclick", "addContainer(1)").appendTo(ul);
																$('<li>Add Container (Left)</li>').attr("onclick", "addContainer(2)").appendTo(ul);
																$('<li>Split (New Up)</li>').attr("onclick", "addContainer(3)").appendTo(ul);
																$('<li>Split (New Down)</li>').attr("onclick", "addContainer(4)").appendTo(ul);
															} else if(tileContainer.parent().hasClass(verticalStack)) {
																$('<li>Add Container (Above)</li>').attr("onclick", "addContainer(3)").appendTo(ul);
																$('<li>Add Container (Below)</li>').attr("onclick", "addContainer(4)").appendTo(ul);
																$('<li>Split (New Right)</li>').attr("onclick", "addContainer(1)").appendTo(ul);
																$('<li>Split (New Left)</li>').attr("onclick", "addContainer(2)").appendTo(ul);
															} else {
																$('<li>Add Container (Right)</li>').attr("onclick", "addContainer(1)").appendTo(ul);
																$('<li>Add Container (Left)</li>').attr("onclick", "addContainer(2)").appendTo(ul);
																$('<li>Add Container (Above)</li>').attr("onclick", "addContainer(3)").appendTo(ul);
																$('<li>Add Container (Below)</li>').attr("onclick", "addContainer(4)").appendTo(ul);
															}
															
															if(tileContainer.siblings().size() == 0 && tileContainer.parent().parent().attr('id') == 'content') {
																//do nothing
															} else {
																$('<li>Delete</li>').attr("onclick", "deleteTileContainer()").appendTo(ul);
															}
															
															//position
															$(ul).css({
															        position: 'absolute',
															        top:ev.pageY, 
															        left: ev.pageX,
															        'z-index': '10'
															    }).show();
															
															//stop propagation to parent nodes
															ev.stopPropagation();
															
															//this makes sure that browser's default context menu is not shown
															return false;
													   });
	
	$('.tileContainer.pseudo-new').removeClass('pseudo-new');
}
